#!/bin/bash

# cjgit - Cangjie Git Manager
# Main dispatcher script that calls individual command scripts

# Get the directory where this script is located
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# Function to print colored output (minimal version for error messages)
print_error() {
    echo -e "\033[0;31m[ERROR]\033[0m $1"
}

print_info() {
    echo -e "\033[0;34m[INFO]\033[0m $1"
}

print_success() {
    echo -e "\033[0;32m[SUCCESS]\033[0m $1"
}

print_warning() {
    echo -e "\033[1;33m[WARNING]\033[0m $1"
}

# Function to check if current directory is inside a Cangjie sub-project
# and change to the projects root directory if needed
ensure_projects_root() {
    local current_dir="$(pwd)"
    
    # Source the common functions to get the PROJECTS array
    source "$SCRIPT_DIR/cjgit-common.sh" >/dev/null 2>&1
    
    # Always search upward from current directory to find projects root
    local search_dir="$current_dir"
    local projects_root_found=""
    
    while [[ "$search_dir" != "/" ]]; do
        # Check if this directory contains at least one Cangjie project directory that is a git repo
        for project in "${PROJECTS[@]}"; do
            if [[ -d "$search_dir/$project/.git" ]]; then
                projects_root_found="$search_dir"
                break 2  # Break out of both loops
            fi
        done
        
        # Move up one directory
        search_dir="$(dirname "$search_dir")"
    done
    
    # If we found the projects root and it's different from current directory
    if [[ -n "$projects_root_found" ]] && [[ "$projects_root_found" != "$current_dir" ]]; then
        cd "$projects_root_found"
        print_info "Changed to projects root: $projects_root_found"
        return 0
    elif [[ -n "$projects_root_found" ]]; then
        # Already in projects root
        return 0
    else
        # Could not find projects root
        print_warning "Could not locate Cangjie projects root directory"
        print_warning "Current directory: $current_dir"
        print_warning "Looking for directories: ${PROJECTS[*]}"
        return 1
    fi
}

# Function to check if a command exists and meets minimum version requirement
check_tool_version() {
    local tool_name="$1"
    local min_version="$2"
    local version_pattern="$3"
    
    # Check if tool exists
    if ! command -v "$tool_name" >/dev/null 2>&1; then
        print_error "$tool_name is not installed or not in PATH"
        return 1
    fi
    
    # Get version
    local version
    if [[ "$tool_name" == "bash" ]]; then
        version="$BASH_VERSION"
    else
        version="$("$tool_name" --version 2>/dev/null | head -1 | grep -oP "$version_pattern" | head -1)"
    fi
    
    if [[ -z "$version" ]]; then
        print_warning "Could not determine $tool_name version (using anyway)"
        return 0
    fi
    
    # Compare versions
    if [[ "$(printf '%s\n' "$min_version" "$version" | sort -V | head -1)" != "$min_version" ]]; then
        print_error "$tool_name version $version is less than required minimum $min_version"
        return 1
    fi
    
    # Silent success - no output when version check passes
    return 0
}

# Ensure we're in the projects root directory
# For clone and help: try to find root but don't fail if not found
# For other commands: fail if root not found
if [[ "${1:-help}" == "clone" ]] || [[ "${1:-help}" == "help" ]] || [[ "${1:-help}" == "--help" ]] || [[ "${1:-help}" == "-h" ]]; then
    # For clone and help, just try to find root but continue even if not found
    ensure_projects_root >/dev/null 2>&1
else
    # For other commands, fail if root not found
    if ! ensure_projects_root; then
        print_error "Could not locate Cangjie projects root directory"
        print_error "Please run cjgit commands from the projects root directory"
        exit 1
    fi
fi

# Check required tools and versions

# Check bash version (minimum 4.0)
if ! check_tool_version "bash" "4.0" '[0-9]+\.[0-9]+\.[0-9]+'; then
    print_error "Bash version 4.0+ is required"
    exit 1
fi

# Check git version (minimum 2.22.0 for git branch --show-current)
if ! check_tool_version "git" "2.22.0" '[0-9]+\.[0-9]+\.[0-9]+'; then
    print_error "Git version 2.22.0+ is required"
    exit 1
fi

# Check jq version (minimum 1.5 for jq -n --arg)
if ! check_tool_version "jq" "1.5" '[0-9]+\.[0-9]+'; then
    print_warning "jq version 1.5+ is required for PR creation functionality"
    print_warning "PR commands will not work without jq"
fi

# Check curl version (minimum 7.0 for basic functionality)
if ! check_tool_version "curl" "7.0" '[0-9]+\.[0-9]+'; then
    print_warning "curl version 7.0+ is required for PR creation functionality"
    print_warning "PR commands will not work without curl"
fi

# Function to check if a command script exists
check_command_script() {
    local command="$1"
    local script_path="$SCRIPT_DIR/cjgit-$command.sh"
    
    if [[ ! -f "$script_path" ]]; then
        print_error "Command script not found: $script_path"
        print_error "Please ensure all cjgit command scripts are present in $SCRIPT_DIR"
        return 1
    fi
    
    return 0
}

# Function to execute a command script
execute_command() {
    local command="$1"
    shift
    local script_path="$SCRIPT_DIR/cjgit-$command.sh"
    
    if check_command_script "$command"; then
        source "$script_path" "$@"
        return $?
    else
        return 1
    fi
}

# Help command implementation
help_command() {
    execute_command "help"
}

# Main script logic
case "${1:-help}" in
    clone)
        shift
        execute_command "clone" "$@"
        ;;
    new)
        if [[ -z "$2" ]]; then
            print_error "Branch name is required for 'new' command"
            echo
            help_command
            exit 1
        fi
        execute_command "new" "$2"
        ;;
    pull)
        execute_command "pull"
        ;;
    push)
        shift
        execute_command "push" "$@"
        ;;
    pr)
        if [[ -z "$2" ]]; then
            print_error "PR title is required for 'pr' command"
            echo
            help_command
            exit 1
        fi
        execute_command "pr" "$2"
        ;;
    status)
        execute_command "status"
        ;;
    help|--help|-h)
        help_command
        ;;
    *)
        print_error "Unknown command: $1"
        echo
        help_command
        exit 1
        ;;
esac